import 'package:agora_rtm/src/impl/gen/rtm_result_handler.dart';
import 'package:agora_rtm/src/impl/extensions.dart';
import 'package:agora_rtm/src/binding_forward_export.dart';
import 'package:agora_rtm/src/bindings/gen/agora_stream_channel_impl.dart'
    as native_binding;
import 'package:flutter/services.dart';

import 'agora_rtm_client_ohos_impl.dart';

class StreamChannelOhosImpl implements StreamChannel {
  StreamChannelOhosImpl(this._methodChannel,this.rtmResultHandler);
  
  final RtmResultHandler rtmResultHandler;

  final MethodChannel _methodChannel;

  @override
  Future<(RtmStatus, String?)> getChannelName() async {
    final Map<String, dynamic> args = {
    };
    var code = await _methodChannel.invokeMethod<String>("getChannelName", args);
    return (RtmClientOhosImpl.getRtmStatus(0),code);
  }

  @override
  Future<(RtmStatus, GetSubscribedUserListResult?)> getSubscribedUserList(String topic) async {
    final Map<String, dynamic> args = {
      "topic":topic
    };
    var code = await _methodChannel.invokeMethod<String>("getSubscribedUserList", args);
    Map<String,dynamic> map = jsonDecode(code!);
    GetSubscribedUserListResult result = GetSubscribedUserListResult(channelName: '',topic: topic,users: UserList.fromJson(jsonDecode(map['userList'])));
    return (RtmClientOhosImpl.getRtmStatus(map['errorCode']),result);
  }

  @override
  Future<(RtmStatus, JoinResult?)> join({String? token, bool withMetadata = false, bool withPresence = true, bool withLock = false, bool beQuiet = false}) async {
    final Map<String, dynamic> options = {
      "token":token,
      "withMetadata":withMetadata,
      "withPresence":withPresence,
      "withLock":withLock,
    };
    final Map<String, dynamic> args = {
      "options":jsonEncode(options),
    };
    var code = await _methodChannel.invokeMethod<String>("join", args);
    Map<String,dynamic> map = jsonDecode(code!);
    final (JoinResult result, RtmErrorCode errorCode) = await rtmResultHandler.request(int.parse(map['requestId']));
    return (RtmClientOhosImpl.getRtmStatus(map['errorCode']),result);
  }

  @override
  Future<(RtmStatus, JoinTopicResult?)> joinTopic(String topic, {RtmMessageQos qos = RtmMessageQos.unordered, RtmMessagePriority priority = RtmMessagePriority.normal, String meta = '', bool syncWithMedia = false}) async {
    final Map<String, dynamic> options = {
      "qos":qos.value(),
      "priority":priority.value(),
      "metadata":meta,
      "syncWithMedia":syncWithMedia,
    };
    final Map<String, dynamic> args = {
      "topic":topic,
      "options":jsonEncode(options),
    };
    var code = await _methodChannel.invokeMethod<String>("joinTopic", args);
    Map<String,dynamic> map = jsonDecode(code!);
    final (JoinTopicResult result, RtmErrorCode errorCode) = await rtmResultHandler.request(int.parse(map['requestId']));
    return (RtmClientOhosImpl.getRtmStatus(map['errorCode']),result);
  }

  @override
  Future<(RtmStatus, LeaveResult?)> leave() async {
    final Map<String, dynamic> args = {
    };
    var code = await _methodChannel.invokeMethod<String>("leave", args);
    Map<String,dynamic> map = jsonDecode(code!);
    final (LeaveResult result, RtmErrorCode errorCode) = await rtmResultHandler.request(int.parse(map['requestId']));
    return (RtmClientOhosImpl.getRtmStatus(map['errorCode']),result);
  }

  @override
  Future<(RtmStatus, LeaveTopicResult?)> leaveTopic(String topic) async {
    final Map<String, dynamic> args = {
      "topic":topic
    };
    var code = await _methodChannel.invokeMethod<String>("leaveTopic", args);
    Map<String,dynamic> map = jsonDecode(code!);
    final (LeaveTopicResult result, RtmErrorCode errorCode) = await rtmResultHandler.request(int.parse(map['requestId']));
    return (RtmClientOhosImpl.getRtmStatus(map['errorCode']),result);
  }

  @override
  Future<(RtmStatus, PublishTopicMessageResult?)> publishBinaryMessage(String topic, Uint8List message, {int sendTs = 0, String? customType}) {
    // TODO: implement publishBinaryMessage
    throw UnimplementedError();
  }

  @override
  Future<(RtmStatus, PublishTopicMessageResult?)> publishTextMessage(String topic, String message, {int sendTs = 0, String? customType}) {
    // TODO: implement publishTextMessage
    throw UnimplementedError();
  }

  @override
  Future<RtmStatus> release() async {
    final Map<String, dynamic> args = {
    };
    var code = await _methodChannel.invokeMethod<int>("releaseStreamChannel", args);
    return RtmClientOhosImpl.getRtmStatus(code!);
  }

  @override
  Future<(RtmStatus, RenewTokenResult?)> renewToken(String token) async {
    final Map<String, dynamic> args = {
      "token":token
    };
    var code = await _methodChannel.invokeMethod<int>("renewTokenStreamChannel", args);
    return (RtmClientOhosImpl.getRtmStatus(code!),null);
  }

  @override
  Future<RtmStatus> setParameters(String parameters) {
    // TODO: implement setParameters
    throw UnimplementedError();
  }

  @override
  Future<(RtmStatus, SubscribeTopicResult?)> subscribeTopic(String topic, {List<String> users = const []}) async {
    final Map<String, dynamic> options = {
      "users":users
    };
    final Map<String, dynamic> args = {
      "topic":topic,
      "options":jsonEncode(options),
    };
    var code = await _methodChannel.invokeMethod<String>("subscribeTopic", args);
    Map<String,dynamic> map = jsonDecode(code!);
    final (SubscribeTopicResult result, RtmErrorCode errorCode) = await rtmResultHandler.request(int.parse(map['requestId']));
    return (RtmClientOhosImpl.getRtmStatus(map['errorCode']),result);
  }

  @override
  Future<(RtmStatus, UnsubscribeTopicResult?)> unsubscribeTopic(String topic, {List<String> users = const []}) async {
    final Map<String, dynamic> options = {
      "users":users
    };
    final Map<String, dynamic> args = {
      "topic":topic,
      "options":jsonEncode(options),
    };
    var code = await _methodChannel.invokeMethod<int>("unsubscribeTopic", args);
    return (RtmClientOhosImpl.getRtmStatus(code!),null);
  }

}
